home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 August: Technology Seed / ADC Seed CD - August 1999.toast / NSL 1.1 Beta SDK / Sample Code / Test.c < prev   
Encoding:
C/C++ Source or Header  |  1999-07-06  |  18.4 KB  |  651 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        Test.c
  3.  
  4.     Contains:    xxx put contents here xxx
  5.  
  6.     Written by:    Kevin Arnold - based on sample code from Nav services written by Tony Bacigalupi
  7.  
  8.     Copyright:    © 1998 - 1999 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.     <17>    05-11-99    sns        remove endless error loop in TestSyncNeighborhoodLookup()
  13.     <16>    03-24-99    KA        converting to new headers
  14.     <15>    03-22-99    KA        converting to new data type names (ie NSLxxx) and handle NSLStandardGetURL returning OSStatus
  15.     <14>    02-23-99    KA        added parameter to the NSLGetStandardURL call
  16.     <13>    02-05-99    KA        added async calling to NSL
  17.     <12>    01-12-99    KA        put back reference to NSLStandardGetURL and use new parsing pb call
  18.     <11>    12-15-98    KA        removed reference to NSLStandardGetURL
  19.     <10>    11-05-98    KA        removed reference to NSLStandardURL.h
  20.     <09>    10-20-98    KA        fixed bug in non-fatal error handling
  21.     <08>    10-15-98    KA        added showURLTEField param option
  22.     <06>    10/08/98    KA        added filter proc param to NSLStandardGetURL call
  23.     <05>     8/25/98    KA        we weren't setting done to false in the beginning of TestSyncServicesLookup
  24.     <04>     8/12/98    KA        added cleanup calls to free our NSL made objects
  25.     <03>     7/21/98    KA        added NSLErrorToString calls
  26.     <01>     4/06/98    KA        Initial check-in.
  27.  
  28.     To Do:
  29. */
  30.  
  31. #include "NSL.h"
  32.  
  33.  
  34. #if PROFILE
  35. #include <Profiler.h>
  36. #endif
  37.  
  38. #include <StdIO.h>
  39. #include <string.h>
  40.  
  41. #include <Threads.h>
  42.  
  43. #ifdef __MWERKS__
  44. #include <SIOUX.h>
  45. #endif
  46.  
  47.  
  48. #define kWebServerType        "http"
  49. #define kFTPServerType        "ftp"
  50. #define kAppleShareType        "AFPServer"
  51. #define kLaserWriterType    "LaserWriter"
  52.  
  53. NSLClientRef        gOurClientRef;
  54. char                gErrorString[256];
  55. char                gSolutionString[256];
  56.  
  57. void TestDefaultNeighborhoodLookup( void );
  58. void TestSyncNeighborhoodLookup( NSLNeighborhood neighborhood ); 
  59. void TestSyncServicesLookup( char* service );
  60. void TestAsyncServicesLookup( char* service );
  61. void TestStandardRegisterURL(void);
  62. void TestStandardDeregisterURL(void);
  63. void DoNSLFatalAlert( NSLError theError );
  64. void DoNSLNonFatalAlert( NSLError theError, Boolean* cancelSearch );
  65.  
  66. static char GetPressedKey()
  67. {
  68.     char c;
  69.     char dummy;
  70.     
  71.     scanf("%c%c", &c, &dummy);
  72.     
  73.     return c;
  74. }
  75.  
  76. void DoNSLFatalAlert( NSLError theError )
  77. {
  78.     char    errorString[256];
  79.     char    solutionString[256];
  80.     
  81.     // call this if you don't want to give the user the option of canceling the search
  82.     NSLErrorToString( theError, errorString, solutionString );
  83.     printf( "Fatal error occurred: %ld\r%s\r%s\r", theError.theErr, errorString, solutionString );
  84. }
  85.  
  86. void DoNSLNonFatalAlert( NSLError theError, Boolean* cancelSearch )
  87. {
  88.     char    errorString[256];
  89.     char    solutionString[256];
  90.     char    result;
  91.     
  92.     // call this if the error isn't fatal and the user might want to continue/cancel the search
  93.     NSLErrorToString( theError, errorString, solutionString );
  94.     printf( "Non Fatal error occurred: %ld\r%s\r%s\r", theError.theErr, errorString, solutionString );
  95.     printf( "Press Y to continue or N to cancel" );
  96.  
  97.     result = GetPressedKey();
  98.     
  99.     if ( result == 'y' || result == 'Y' )
  100.         *cancelSearch = false;
  101.     else
  102.         *cancelSearch = true;
  103. }
  104.  
  105.  
  106. void main()
  107. {
  108.     OSStatus                status;
  109.     Boolean                 quit        = false;
  110.     Boolean                    doBanner    = true;
  111.     Ptr                        url;
  112.     NSLDialogOptions        options;
  113. //    NSLEventUPP             eventUPP = NewNSLEventUPP(OurEventHandler);
  114.     
  115.         
  116.     #ifdef __MWERKS__
  117.     SIOUXSettings.asktosaveonclose = 0;
  118.     #endif
  119.  
  120.     #if PROFILE
  121.     ProfilerInit(collectDetailed, bestTimeBase, 500, 20);
  122.     #endif
  123.  
  124.     printf("NSL API Test\rGenerated %s at %s\r\r", __DATE__, __TIME__);
  125.  
  126.     status = NSLOpenNavigationAPI( &gOurClientRef );
  127.     
  128.     if ( status && status != kNSLSomePluginsFailedToLoad )
  129.         printf("NSLAPI could not be opened due to an internal error\r");
  130.     else
  131.     {
  132.         if ( status == kNSLSomePluginsFailedToLoad )
  133.         {
  134.             // this isn't a fatal error, so we want to let someone know but we will continue.
  135.             NSLError    cludgeError;            // we have to crock one as this is the only time we will get back an OSStatus
  136.                                                 // instead of an NSLError.  Just make theContext be zero
  137.             cludgeError.theErr = status;
  138.             cludgeError.theContext = 0;
  139.             
  140.             NSLErrorToString( cludgeError, gErrorString, gSolutionString );
  141.             printf("Error #%ld: %s\r", cludgeError.theErr, gErrorString );
  142.             printf("Solution: %s\r", gSolutionString );
  143.         }
  144.         
  145.         do {
  146.             char c;
  147.             
  148.             if ( doBanner )
  149.                 printf("\r\r\rPlease make a choice [1-6 and hit return]:\r\t1 - Get list of Default Neighborhoods available\r\t2 - Get list of Webservers in a Neighborhood(sync)\r\t3 - Get list of Webservers in a Neighborhood(async)\r\t4 - Get list of AppleShare servers in a Neighborhood\r\t5 - Browse for url\r\t6 - QUIT\r\r> ");
  150.  
  151.             c = GetPressedKey();        
  152.             
  153.             doBanner = true;
  154.             
  155.             switch ( c)
  156.             {
  157.                 case '1':
  158.                     TestDefaultNeighborhoodLookup();
  159.                     break;
  160.                     
  161.                 case '2':
  162.                     TestSyncServicesLookup(kWebServerType);
  163.                     break;
  164.                     
  165.                 case '3':
  166.                     TestAsyncServicesLookup(kWebServerType);
  167.                     break;
  168.                     
  169.                 case '4':
  170.                     TestSyncServicesLookup(kAppleShareType);
  171.                     break;
  172.                     
  173.                 case '5':
  174.                     NSLGetDefaultDialogOptions( &options );
  175.                     
  176.                     status = NSLStandardGetURL( &options, nil, nil, nil, "Web,http,https;FTP,ftp;AppleShare,AFPServer,afp;", &url );
  177.                     
  178.                     if ( status == noErr )
  179.                     {
  180.                         printf( "\rURL Returned: %s\r", url );
  181.                         url = NSLFreeURL( url );
  182.                     }
  183.                     else if ( status == kNSLUserCanceled )
  184.                         printf( "\rUser Canceled URL Selection\r");
  185.                     else
  186.                         printf( "\rNSLStandardGetURL returned: %ld", status );
  187.                     
  188.                     break;
  189.                     
  190.                 case '6':
  191.                     printf("Bye now!\r");
  192.                     quit = true;
  193.                     break;
  194.                 
  195.                 default:
  196.                     doBanner = false;
  197.             }
  198.  
  199.         } while ( quit == false );
  200.     }
  201.     
  202.     #if PROFILE
  203.     ProfilerDump("\pPerformances");
  204.     ProfilerTerm();
  205.     #endif
  206.     
  207.     ExitToShell();
  208. }
  209.  
  210. #define    kBufferLength    4096
  211.  
  212. void TestDefaultNeighborhoodLookup( void )
  213. {
  214.     NSLNeighborhood neighborhood;
  215.     
  216.     printf( "Getting default NSLNeighborhoods\r\r" );
  217.     
  218.     neighborhood = NSLMakeNewNeighborhood( "", NULL );        // empty string for default neighborhood lookup, NULL for empty protocol string 
  219.                                                             // meaning we want all default neighborhoods
  220.     TestSyncNeighborhoodLookup( neighborhood );
  221.  
  222.     NSLFreeNeighborhood( neighborhood );                    // make sure we free up this memory
  223. }
  224.  
  225.  
  226.  
  227. void TestSyncNeighborhoodLookup( NSLNeighborhood neighborhood )
  228. {
  229.     char                tempName[256];
  230.     long                bufLen = kBufferLength;
  231.     char*                buffer = NULL;
  232.     char*                tempPtr = NULL;
  233.     NSLRequestRef        ourRequestRef;
  234.     NSLClientAsyncInfoPtr    ourAsyncInfo;
  235.     NSLError            iErr = kNSLErrorNoErr;
  236.     NSLNeighborhood        nhPtr = NULL;
  237.     long                nhLength, tempPtrLength;
  238.     Boolean                done = false;
  239.     
  240.     printf( "Looking up Neighborhoods\r\r" );
  241.     
  242.     buffer = NewPtr( bufLen );
  243.     
  244.     // first prepare the request which will set up a NSLClientAsyncInfoPtr for us
  245.     iErr = NSLPrepareRequest( NULL, NULL, gOurClientRef, &ourRequestRef, buffer, bufLen, &ourAsyncInfo );
  246.  
  247.     if ( iErr.theErr )
  248.     {
  249.         printf("NSLPrepareRequest returned error %ld\r", iErr.theErr );
  250.         NSLErrorToString( iErr, gErrorString, gSolutionString );
  251.         printf("Error: %s\r", gErrorString );
  252.         printf("Solution: %s\r", gSolutionString );
  253.     }
  254.         
  255.     // set the values of ourAsyncInfo pb
  256.     ourAsyncInfo->clientContextPtr = NULL;
  257.     ourAsyncInfo->maxSearchTime = 0;        // no max search time
  258.     ourAsyncInfo->alertInterval = 0;         // no alert interval
  259.     ourAsyncInfo->alertThreshold = 1;        // make alert threshold every item...
  260.  
  261.     if ( iErr.theErr == noErr )
  262.         iErr = NSLStartNeighborhoodLookup( ourRequestRef, neighborhood, ourAsyncInfo );
  263.     
  264.     do {
  265.         if ( iErr.theErr == noErr && ourAsyncInfo->totalItems > 0 )
  266.         {
  267.             while ( NSLGetNextNeighborhood( ourAsyncInfo, &nhPtr, &nhLength ) )
  268.             {        
  269.                 if ( nhLength > 0 && nhLength < kBufferLength  )
  270.                 {
  271.                     NSLGetNameFromNeighborhood( nhPtr, &tempPtr, &tempPtrLength );
  272.                     memcpy( tempName, tempPtr, tempPtrLength );
  273.                     tempName[tempPtrLength] = '\0';
  274.  
  275.                     printf( "%s\r", tempName );
  276.                 }
  277.             }
  278.         }
  279.         
  280.         if ( ourAsyncInfo->searchState == kNSLSearchStateComplete )
  281.             done = true;
  282.         else
  283.             iErr = NSLContinueLookup( ourAsyncInfo );    // <17> if search state isn't complete, then the error isn't fatal
  284.         
  285.     } while ( !iErr.theErr && !done );
  286.     
  287.     if ( iErr.theErr )
  288.     {
  289.         NSLErrorToString( iErr, gErrorString, gSolutionString );
  290.         printf("Error: %s\r", gErrorString );
  291.         printf("Solution: %s\r", gSolutionString );
  292.     }    
  293.     
  294.     if ( buffer )
  295.         DisposePtr(buffer);
  296. }
  297.  
  298. void TestSyncServicesLookup( char* service )
  299. {
  300.     char                name[256] = "\p";
  301.     char                url[1024];
  302.     long                bufLen = kBufferLength;
  303.     char*                buffer = NewPtr( bufLen );
  304.     NSLRequestRef        ourRequestRef;
  305.     NSLClientAsyncInfoPtr    ourAsyncInfo;
  306.     NSLError            iErr = kNSLErrorNoErr;
  307.     NSLServicesList        serviceList = NULL;
  308.     NSLTypedDataPtr         newDataPtr = NULL;
  309.     NSLNeighborhood        neighborhood, urlPtr = NULL;
  310.     long                urlLength;
  311.     Boolean                done = false;
  312.     char                c;
  313.     
  314.     printf( "Please Type in the neighborhood you want to search then hit return\r" );
  315.     scanf("%c", &c );
  316.     
  317.     while ( c != '\r' && c != '\n' && name[0] < 256 )
  318.     {
  319.         name[0]++;
  320.         name[name[0]] = c;
  321.         scanf("%c", &c );
  322.     };
  323.     
  324.     p2cstr( (unsigned char*)name );
  325.     
  326.     neighborhood = NSLMakeNewNeighborhood( name, NULL );
  327.     printf( "Looking up Service\r\r" );
  328.     
  329.     // first prepare the request which will set up a NSLClientAsyncInfoPtr for us
  330.     iErr = NSLPrepareRequest( NULL, NULL, gOurClientRef, &ourRequestRef, buffer, bufLen, &ourAsyncInfo );
  331.  
  332.     if ( iErr.theErr )
  333.     {
  334.         printf("NSLPrepareRequest returned error %ld\r", iErr.theErr );
  335.  
  336.         NSLErrorToString( iErr, gErrorString, gSolutionString );
  337.         printf("Error #%ld: %s\r", iErr.theErr, gErrorString );
  338.         printf("Solution: %s\r", gSolutionString );
  339.     }
  340.     else
  341.     {
  342.         serviceList = NSLMakeNewServicesList( service );    // we can pass a comma delimited cstring here (ie "http,ftp")
  343.         
  344.         // now we need to create a NSLTypedDataPtr which holds teh serviceList info as well as an attribute if we wish
  345.         if ( serviceList != NULL )
  346.         {
  347.             iErr.theErr = NSLMakeServicesRequestPB( serviceList, &newDataPtr );    // we can also pass an attribute if we want to get more specific
  348.             NSLDisposeServicesList( serviceList );                            // we are done with this, free this memory!        
  349.         }
  350.         
  351.         // set the values of ourAsyncInfo pb
  352.         ourAsyncInfo->clientContextPtr = NULL;
  353.         ourAsyncInfo->maxSearchTime = 0;        // no max search time
  354.         ourAsyncInfo->alertInterval = 0;         // no alert interval
  355.         ourAsyncInfo->alertThreshold = 1;        // make alert threshold every item...
  356.  
  357.         if ( iErr.theErr == noErr )
  358.             iErr = NSLStartServicesLookup( ourRequestRef, neighborhood, newDataPtr, ourAsyncInfo );
  359.  
  360.         do {
  361.             if ( iErr.theErr == noErr && ourAsyncInfo->totalItems > 0 )
  362.             {
  363.                 while ( NSLGetNextUrl( ourAsyncInfo, &urlPtr, &urlLength ) )
  364.                 {        
  365.                     if ( urlLength > 0 )
  366.                     {
  367.                         memcpy( url, urlPtr, urlLength );
  368.                         url[urlLength] = '\0';
  369.                         printf( "%s\r", url );
  370.                     }
  371.                 }
  372.             }
  373.             else if ( iErr.theErr )
  374.             {
  375.                 NSLErrorToString( iErr, gErrorString, gSolutionString );
  376.                 printf("Error #%ld: %s\r", iErr.theErr, gErrorString );
  377.                 printf("Solution: %s\r", gSolutionString );
  378.             }
  379.                     
  380.             if ( ourAsyncInfo->searchState == kNSLSearchStateComplete )
  381.                 done = true;
  382.             else
  383.                 iErr = NSLContinueLookup( ourAsyncInfo );    // if search state isn't complete, then the error isn't fatal
  384.  
  385.         } while ( !done );                                    // it is possible to get errors back, but if the search state isn't complete, then one or more
  386.                                                             // plugins are still working!
  387.  
  388.         NSLFreeTypedDataPtr( newDataPtr );                    // dispose this
  389.     }
  390.     
  391.     NSLFreeNeighborhood( neighborhood );                    // make sure we free up this memory
  392.     
  393.     if ( buffer )
  394.         DisposePtr(buffer);
  395. }
  396.  
  397. typedef struct {
  398.     NSLRequestRef            theRequestRef;
  399.     NSLTypedDataPtr            theRequestDataPtr;
  400.     Boolean                    lookupFinished;
  401. } LookupContext, *LookupContextPtr;
  402.  
  403. pascal void ServicesLookupNotifyProc( NSLClientAsyncInfoPtr nslInfoPtr );
  404. pascal void ServicesLookupNotifyProc( NSLClientAsyncInfoPtr nslInfoPtr )
  405. {
  406.     LookupContextPtr    lookupContext = (LookupContextPtr)nslInfoPtr->clientContextPtr;
  407.     char*                curURL;
  408.     char*                urlPtr = NULL;
  409.     NSLError            nslError;
  410.     long                urlLength;
  411.     Boolean                weDone = false, cancelSearch = false;;
  412.     
  413.     // first check our ptrs and to see if this is from the current request
  414.     if ( nslInfoPtr && lookupContext )
  415.     {
  416.         // we might want to think about putting up an alert message here if we have received one...
  417.         if ( nslInfoPtr->searchResult.theErr )
  418.         {
  419.             if ( nslInfoPtr->searchState != kNSLSearchStateComplete )
  420.             {
  421.                 DoNSLNonFatalAlert( nslInfoPtr->searchResult, &cancelSearch );
  422.             }
  423.             else
  424.             {
  425.                 DoNSLFatalAlert( nslInfoPtr->searchResult );        // user has no choice
  426.                 cancelSearch = true;
  427.             }
  428.         }
  429.         
  430.         if ( nslInfoPtr->totalItems > 0 && !cancelSearch )
  431.         {
  432.             while ( NSLGetNextUrl( nslInfoPtr, &urlPtr, &urlLength ) )
  433.             {        
  434.                 if ( urlLength > 0 )
  435.                 {
  436.                     curURL = NewPtr( urlLength + 1 );                    // The NSL Manager WON'T call us at interrupt time so mem aloocation is OK!
  437.                     
  438.                     BlockMove( urlPtr, curURL, urlLength );
  439.                     curURL[urlLength] = '\0';                            // null terminate!
  440.                 }
  441.                 else
  442.                 {
  443.                     weDone = true;
  444.                 }
  445.                 
  446.                 if ( !weDone )
  447.                 {
  448.                     printf( "%s\r", curURL );
  449.                 }
  450.                 
  451.                 if ( curURL )
  452.                     DisposePtr( curURL );                                // now we could just have curURL be on the stack in this case but to show that 
  453.                                                                         // memory allocation is cool in the notifier we did it this way...
  454.                 
  455.                 curURL = NULL;
  456.             }
  457.         }
  458.     
  459.         if ( !cancelSearch && nslInfoPtr->searchState != kNSLSearchStateComplete )
  460.         {
  461.             nslError = NSLContinueLookup(nslInfoPtr);                    // don't forget to call NSLContinueLookup when you are done with the data in the buffer!
  462.             
  463.             if ( nslError.theErr )
  464.             {
  465.                 if ( nslInfoPtr->searchState != kNSLSearchStateComplete )
  466.                 {
  467.                     DoNSLNonFatalAlert( nslError, &cancelSearch );
  468.                 }
  469.                 else
  470.                 {
  471.                     DoNSLFatalAlert( nslError );        // user has no choice
  472.                     cancelSearch = true;
  473.                 }
  474.             }
  475.         }
  476.         
  477.         if ( !cancelSearch && nslInfoPtr->searchState == kNSLSearchStateComplete )
  478.         {
  479.             lookupContext->lookupFinished = true;
  480.             nslError = NSLDeleteRequest( lookupContext->theRequestRef );
  481.             
  482.             if ( nslError.theErr )
  483.                 DoNSLFatalAlert( nslError );        // user has no choice
  484.         }
  485.         else if ( cancelSearch )                    // user decided error was bad enough to cancel the entire search
  486.         {
  487.             lookupContext->lookupFinished = true;
  488.             nslError = NSLCancelRequest( lookupContext->theRequestRef );
  489.             
  490.             if ( nslError.theErr == noErr )
  491.                 nslError = NSLDeleteRequest( lookupContext->theRequestRef );
  492.         }
  493.     }
  494. }
  495.  
  496.  
  497.  
  498. void TestAsyncServicesLookup( char* service )
  499. {
  500.     char                name[256] = "\p";
  501.     long                bufLen = kBufferLength;
  502.     char*                buffer = NewPtr( bufLen );
  503.     LookupContextPtr    contextPtr;
  504.     NSLRequestRef        ourRequestRef;
  505.     NSLClientAsyncInfoPtr    ourAsyncInfo;
  506.     NSLError            iErr = kNSLErrorNoErr;
  507.     NSLServicesList        serviceList = NULL;
  508.     NSLTypedDataPtr         newDataPtr = NULL;
  509.     NSLNeighborhood        neighborhood, urlPtr = NULL;
  510.     Boolean                done = false;
  511.     char                c;
  512.     
  513.     printf( "Please Type in the neighborhood you want to search then hit return\r" );
  514.     scanf("%c", &c );
  515.     
  516.     while ( c != '\r' && c != '\n' && name[0] < 256 )
  517.     {
  518.         name[0]++;
  519.         name[name[0]] = c;
  520.         scanf("%c", &c );
  521.     };
  522.     
  523.     p2cstr( (unsigned char*)name );
  524.     
  525.     neighborhood = NSLMakeNewNeighborhood( name, NULL );
  526.     printf( "Looking up Service\r\r" );
  527.     
  528.     // first prepare the request which will set up a NSLClientAsyncInfoPtr for us
  529.     contextPtr = NewPtr( sizeof( LookupContext ) );
  530.     if ( !contextPtr )
  531.     {
  532.         printf( "NewPtr call failed!" );
  533.         return;
  534.     }
  535.     
  536.     iErr = NSLPrepareRequest( ServicesLookupNotifyProc, contextPtr, gOurClientRef, &ourRequestRef, buffer, bufLen, &ourAsyncInfo );
  537.  
  538.     if ( iErr.theErr )
  539.     {
  540.         printf("NSLPrepareRequest returned error %ld\r", iErr.theErr );
  541.  
  542.         NSLErrorToString( iErr, gErrorString, gSolutionString );
  543.         printf("Error #%ld: %s\r", iErr.theErr, gErrorString );
  544.         printf("Solution: %s\r", gSolutionString );
  545.     }
  546.     else
  547.     {
  548.         contextPtr->theRequestRef = ourRequestRef;
  549.         contextPtr->theRequestDataPtr = ourAsyncInfo;
  550.         contextPtr->lookupFinished = false;
  551.         
  552.         serviceList = NSLMakeNewServicesList( service );    // we can pass a comma delimited cstring here (ie "http,ftp")
  553.         
  554.         // now we need to create a NSLTypedDataPtr which holds teh serviceList info as well as an attribute if we wish
  555.         if ( serviceList != NULL )
  556.         {
  557.             iErr.theErr = NSLMakeServicesRequestPB( serviceList, &newDataPtr );    // we can also pass an attribute if we want to get more specific
  558.             NSLDisposeServicesList( serviceList );                            // we are done with this, free this memory!        
  559.         }
  560.         
  561.         // set the values of ourAsyncInfo pb
  562.         ourAsyncInfo->maxSearchTime = 0;        // no max search time
  563.         ourAsyncInfo->alertInterval = 0;         // no alert interval
  564.         ourAsyncInfo->alertThreshold = 1;        // make alert threshold every item...
  565.  
  566.         if ( iErr.theErr == noErr )
  567.             iErr = NSLStartServicesLookup( ourRequestRef, neighborhood, newDataPtr, ourAsyncInfo );
  568.  
  569.         if ( iErr.theErr == noErr )
  570.         {
  571.             while ( !contextPtr->lookupFinished )
  572.             {
  573.                 YieldToAnyThread();                            // its important to have a call to YieldToAnyThread in your main event loop
  574.                                                             // which is what we are simulating here...
  575.                 SystemTask();
  576.             }
  577.         }
  578.         
  579.         NSLFreeTypedDataPtr( newDataPtr );                    // dispose this
  580.     }
  581.     
  582.     NSLFreeNeighborhood( neighborhood );                    // make sure we free up this memory
  583.     
  584.     if ( buffer )
  585.         DisposePtr(buffer);
  586. }
  587.  
  588.  
  589. // the code below is provided as an example, but won't work here because we don't have an event loop
  590. // that calls YieldToAnyThread.
  591. void TestStandardRegisterURL(void)
  592. {
  593.     char                url[1024];
  594.     UInt16                index = 0;
  595.     NSLError            regError;
  596.     char                c;
  597.     
  598.     printf( "Please Type in the url you want to register then hit return\r" );
  599.     scanf("%c", &c );
  600.     
  601.     while ( c != '\r' && c != '\n' && index < sizeof(url)-1 )
  602.     {
  603.         url[index++] = c;
  604.         scanf("%c", &c );
  605.     };
  606.     
  607.     url[index] = '\0';        // null terminate this
  608.     
  609.     regError = NSLStandardRegisterURL( url, nil );        // we aren't going to specify a neighborhood to register in, leave it up to the plugins
  610.     
  611.     if ( regError.theErr )
  612.     {
  613.         NSLErrorToString( regError, gErrorString, gSolutionString );
  614.         printf("Error #%ld: %s\r", regError.theErr, gErrorString );
  615.         printf("Solution: %s\r", gSolutionString );
  616.     }
  617.     else
  618.         printf("URL registered");
  619. }
  620.  
  621. void TestStandardDeregisterURL(void)
  622. {
  623.     char                url[1024];
  624.     UInt16                index = 0;
  625.     NSLError            regError;
  626.     char                c;
  627.     
  628.     printf( "Please Type in the url you want to register then hit return\r" );
  629.     scanf("%c", &c );
  630.     
  631.     while ( c != '\r' && c != '\n' && index < sizeof(url)-1 )
  632.     {
  633.         url[index++] = c;
  634.         scanf("%c", &c );
  635.     };
  636.     
  637.     url[index] = '\0';        // null terminate this
  638.     
  639.     regError = NSLStandardDeregisterURL( url, nil );        // we aren't going to specify a neighborhood to deregister in, leave it up to the plugins
  640.     
  641.     if ( regError.theErr )
  642.     {
  643.         NSLErrorToString( regError, gErrorString, gSolutionString );
  644.         printf("Error #%ld: %s\r", regError.theErr, gErrorString );
  645.         printf("Solution: %s\r", gSolutionString );
  646.     }
  647.     else
  648.         printf("URL deregistered");
  649. }
  650.  
  651.